package abel.wlmr.model.unit;

import abel.util.StdBcdNumber;
import abel.wlmr.model.WlmrBaseUnit;
import abel.wlmr.model.WlmrException;
import abel.wlmr.model.type.FlowPointC29Body;
import abel.wlmr.model.type.FlowUnitField;
import io.netty.buffer.ByteBuf;

/**
 * B.5.10.2.4.41 F404： 水表当前正向总累积流量示值
 * 数据单元格式见表 B.104。
 * 表B.104 水表当前数据单元格式
 * 数据内容 数据格式 单 位 字节数
 * 终端抄表时间 见附录 C.15 分时日月年 5
 * 水正向总累积流量示值 见附录 C.29 单位代码 5
 * 
 * @author Abel
 *
 */
public class AfnFirstF404Unit extends WlmrBaseUnit {
    private static final short FIXED_LENGTH = 5 + 5;

    /** 终端抄表时间 见附录 C.15 分时日月年 5 */
    private StdBcdNumber readingTime;

    /**
     * Unit is default to 1.0m3/h.
     */
    private FlowPointC29Body<FlowUnitField> flow = new FlowPointC29Body<>(new FlowUnitField());

    public AfnFirstF404Unit() {
        super();
    }

    public AfnFirstF404Unit(short guessedLen) {
        super(guessedLen);
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitBody#appendBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public ByteBuf appendBuf(ByteBuf buf) {
        if (readingTime == null || readingTime.length() != 5) {
            throw new IllegalArgumentException("readingTime should be 5 bytes long");
        }

        buf.writeBytes(readingTime.toBytes());
        flow.appendBuf(buf);

        return buf;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitBody#parseBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public int parseBuf(ByteBuf buf) throws WlmrException {
        if (checkBuffer(buf) < 0) {
            return -1;
        }

        readingTime = new StdBcdNumber();
        readingTime.populateBytes(buf, 5);

        flow.parseBuf(buf);

        return FIXED_LENGTH;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getMinLength()
     */
    @Override
    public int getMinLength() {
        return FIXED_LENGTH;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getFinalLen()
     */
    @Override
    public short getFinalLen() {
        return FIXED_LENGTH;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return String.format("{readingTime:%s, flow:%s}", readingTime, flow);
    }

    /**
     * 终端抄表时间 见附录 C.15 分时日月年 5
     * 
     * @return the readingTime
     */
    public StdBcdNumber getReadingTime() {
        return readingTime;
    }

    /**
     * 终端抄表时间 见附录 C.15 分时日月年 5
     * 
     * @param readingTime
     *            the readingTime to set
     */
    public void setReadingTime(StdBcdNumber readingTime) {
        if (readingTime == null || readingTime.length() != 5) {
            throw new IllegalArgumentException("readingTime should be 5 bytes long");
        }

        this.readingTime = readingTime;
    }

    /**
     * Unit is default to 1.0m3/h.
     * 水正向总累积流量示值 见附录 C.29 单位代码 5
     * 
     * @return the velocity
     */
    public FlowPointC29Body<FlowUnitField> getVelocity() {
        return flow;
    }

    /**
     * Unit is default to 1.0m3/h.
     * 水正向总累积流量示值 见附录 C.29 单位代码 5
     * 
     * @param velocity
     *            the velocity to set
     */
    public void setVelocity(FlowPointC29Body<FlowUnitField> velocity) {
        if (velocity == null) {
            throw new IllegalArgumentException("velocity can't be null");
        }

        this.flow = velocity;
    }
}
